# -*- coding: utf-8 -*-

import functools
from gtug.models import Post,User,Profile
import gtug.admin.forms
from django.shortcuts import redirect
from django.views.decorators.cache import cache_page
from utils.template import respond,forbidden
from google.appengine.api import users
from gtug.admin import boot

""" 
Verifica se o nivel do usuario tem permissao para executar a funcionalidade chamada
Basicamente essa funcao eh um wrapper que sera chamado pelos functools que sobrescrevem as funcoes chamadas pelo django

O processo eh incremental. Admin acessa tudo; Author v� listagens e cria post; Editor soh cria post
"""
def check_level(level, func, request, *args, **kargs):
    
    if hasattr(request,'user'):
        user = request.user
        profile = user.profile
        
        # ok, acesso garantido
        if profile['id'] <= level and profile['id']>0:
                return func(request, *args, **kargs)
                
    # se nao cair na condicao de que o level eh suficiente, manda para a pagina de erro
    return forbidden(request, 'User level %d required to view this page' % level)

""" 
Seta que a funcao decorada deve ter o nivel de administrador (1) 
Functools permite que uma funcao encapsule a outra, com um conceito de hook. Esse hook valida se o level=1 (admin)
"""
def validate(level=-1):
    def decorator(func):
        def wrapped(request, *args, **kargs):
            return check_level(level, func, request, *args, **kargs)
        return wrapped
    return decorator
    

@validate(User.__profile_map__['ADMIN'])
def add_post(request, id):
    
    p = None
    id = long(id)
    msg=''
    
    # determina se deve mostrar msg de gravacao
    if request.GET.has_key('msg'):
        msg=request.GET['msg']

    # se for maior, entao estou editando um post, carrega instancia
    if id > 0:
        p = Post.get_by_id(id)
        
    # ok, mostra pagina, ainda nao estou recebendo post
    if request.method == 'GET':
        pform = gtug.admin.forms.PostForm(instance=p)
        
    # recebendo um post, vai salvar - novo ou existente
    elif request.method == 'POST':
        pform = gtug.admin.forms.PostForm(request.POST, instance=p)
        if pform.is_valid():
            post = pform.save()
            
            # seta o autor, caso seja o primeiro a postar
            if p is None:
                post.user_author = User.get_by_email(request.user.email())
            
            # formato de leitura
            post.readable_categories = ', '.join([c.title for c in post.get_categories()])
            post.put()
            
            return redirect('/admin/post/%d/?msg=1' % post.key().id())
            
    return respond(request, 'gtug/admin/post.html', {'form': pform, 'msg': msg})

@validate(User.__profile_map__['ADMIN'])
def add_user(request, id):
    
    u = None
    id = long(id)
    msg=''
    
    # dummy - inicia perfis
    Profile.start_values()
    
    # determina se deve mostrar msg de gravacao
    if request.GET.has_key('msg'):
        msg=request.GET['msg']

    # se nao for 0, entao estou editando um formulario, passar a instancia
    if id > 0:
        u = User.get_by_id(id)
        
    # ok, mostra pagina, ainda nao estou recebendo post
    if request.method == 'GET':
        uform = gtug.admin.forms.UserForm(instance=u)
        
    # recebendo um post, vai salvar - novo ou existente
    elif request.method == 'POST':
        uform = gtug.admin.forms.UserForm(request.POST, instance=u)
        if uform.is_valid():
            user = uform.save()
            return redirect('/admin/user/%d/?msg=1' % user.key().id())
            
    return respond(request,'gtug/admin/user.html', {'form': uform, 'msg': msg})

@validate(User.__profile_map__['EDITOR'])
def list_user(request):
    items = User.all().fetch(100)
    return respond(request,'gtug/admin/list_user.html', {'items': items})

@validate(User.__profile_map__['ADMIN'])
def delete_user(request, id):
    u = User.get_by_id(long(id))
    if u:
        u.delete()
    return redirect('/admin/user/list/')
    
@validate(User.__profile_map__['ADMIN'])
def delete_post(request, id):
    p = Post.get_by_id(long(id))
    if p:
        p.delete()
    return redirect('/admin/post/list/')


@validate(User.__profile_map__['EDITOR'])
def list_post(request):
    items = Post.all().order("-published").fetch(100)
    return respond(request,'gtug/admin/list_post.html', {'items': items})

@validate(User.__profile_map__['ADMIN'])
def bootstrap(request):
    boot.startup()
    return respond(request,'gtug/admin/boot.html', {})